/*
 * Copyright (c) 2024 endless-sky
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#include <cstdint>
#include <string>
#include <thread>
#include <atomic>
#include "utils_log.h"

namespace El {
namespace SystemService {

// 系统内存信息
struct SystemMemoryInfo {
    uint64_t total_ram;     // 总物理内存（MB）
    uint64_t free_ram;      // 空闲物理内存（MB）
    uint64_t available_ram; // 可用物理内存（包括可回收的缓存/缓冲区）（MB）
    uint64_t cached_ram;    // 缓存内存（MB）
    uint64_t buffers_ram;   // 缓冲区内存（MB）
    uint64_t used_ram;      // 已使用物理内存（MB）
};

// 进程内存信息
struct ProcessMemoryInfo {
    uint64_t vm_rss;   // 实际使用物理内存（MB）
    uint64_t vm_pss;   // 按比例分配的物理内存（MB）
    uint64_t vm_hwm;   // 历史最大物理内存使用（MB）
    int32_t oom_score; // OOM分数，越高越容易被杀死
    int32_t oom_adj;   // OOM优先级调整值
};

class MemoryMonitor {
public:
    // 内存告警级别
    enum class WarningLevel {
        NORMAL = 0,    // 正常
        WARNING = 1,   // 警告
        CRITICAL = 2,  // 严重
        OOM_DANGER = 3 // OOM危险
    };

    static MemoryMonitor &GetInstance();

    // 启动内存监控
    void Start();

    // 停止内存监控
    void Stop();

    // 获取系统内存信息
    SystemMemoryInfo GetSystemMemoryInfo() const;

    // 获取进程内存信息
    ProcessMemoryInfo GetProcessMemoryInfo() const;

    // 设置警告级别阈值（百分比）
    void SetWarningThresholds(uint32_t warning_percent, uint32_t critical_percent);

    // 设置OOM分数阈值（超过此值时发出OOM危险警告）
    void SetOOMScoreThreshold(int32_t threshold);

    // 设置进程的OOM优先级（-1000到1000，越小越不容易被杀死）
    bool SetOOMAdjustment(int32_t adj);

    // 获取当前告警级别
    WarningLevel GetCurrentWarningLevel() const;

private:
    MemoryMonitor() = default;
    ~MemoryMonitor();

    MemoryMonitor(const MemoryMonitor &) = delete;
    MemoryMonitor &operator=(const MemoryMonitor &) = delete;

    void MonitorThread();
    WarningLevel CheckWarningLevel(const SystemMemoryInfo &sysInfo) const;
    void UpdateMemoryInfo();
    bool UpdateOOMInfo();
    WarningLevel CheckOOMRisk() const;

    bool running_{false};
    uint32_t warning_percent_{80};     // 警告阈值百分比
    uint32_t critical_percent_{90};    // 严重阈值百分比
    int32_t oom_score_threshold_{100}; // OOM分数阈值
    std::thread monitor_thread_;
    mutable std::atomic<WarningLevel> current_level_{WarningLevel::NORMAL};

    // 缓存的内存信息
    mutable SystemMemoryInfo sys_info_{};
    mutable ProcessMemoryInfo proc_info_{};
};

} // namespace SystemService
} // namespace El